/*
 * Worker.cpp
 *
 *      Author: Jerome RD Soine and Christoph A Brand
 *      Institution: Schwarz goup, Institute for Theoretical Physics, Heidelberg University, Germany
 */

#include "../../../include/core/worker/Worker.h"
typedef boost::chrono::duration<long, boost::milli> milliseconds;


Worker::Worker(CellModel * CELL_MODEL, SubstrateModel * SUBSTRATE_MODEL, Comparator * COMPARATOR, int ID)
{

	locked=false;
	id=ID;
	cell_model = CELL_MODEL->clone();
	substrate_model = SUBSTRATE_MODEL->clone();
	comparator = COMPARATOR->clone();
	fitness = 0;
	joinable = false;
}

Worker::~Worker()
{
	delete cell_model;
	delete substrate_model;
	delete comparator;
}

void Worker::init(vector<double> parameters, vector<double> init_config, int ID){
	id=ID;
	cell_model->set_parameters(parameters);
	cell_model->set_initial_configuration(init_config);
}

void Worker::init(vector<double> parameters, int ID){
	id=ID;
	cell_model->set_parameters(parameters);
}


void Worker::work(){

    cell_model->run();
    substrate_model->run(cell_model->get_force_transmissions());
    fitness = comparator->compare_with(substrate_model);

}

double Worker::get_fitness(){
	return fitness;
}

//THREAD MANAGEMENT
void Worker::start()
{
	joinable = true;
	t = boost::thread(&Worker::work, this);
}

void Worker::join(){
	if(joinable)
		t.join();
}

bool Worker::try_join_for(long millisecs){
	milliseconds m(millisecs);
	if(joinable){
		bool joined = t.try_join_for(m);
		if(joined)
			joinable = false;
		return joined;
	}
	else
		return false;
}
